using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF;
using SecretLabs.NETMF.Hardware;
using System.IO.Ports;
using System.Text;
using XBee.Communications;

namespace IMU6DOFV2.Netduino
{

    public class IMU6DOFv2:IDisposable
    {
        #region Members
		private readonly SerialPort serialHandle;
        private bool reading = false;
        private int indexSentence = 0;
        private byte[] tempSentence = new byte[200]; 
        private IMUData imuData = new IMUData();
    	#endregion

        #region Properties
        public IMUData Data { get { return imuData; } }
	    #endregion        
        
        #region Construcctor

        public IMU6DOFv2(string port)
        {
            serialHandle = new SerialPort(port, 38400, Parity.None, 8, StopBits.One);
            serialHandle.Open();
            serialHandle.DataReceived += new SerialDataReceivedEventHandler(serialHandle_DataReceived);
        }
        
        #endregion

        #region InternalMethods
        void serialHandle_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int numc = 0;
            byte data;
            numc = serialHandle.BytesToRead;

            if (numc > 0)
            {
                for (int i = 0; i < numc; i++)
                {	// Process bytes received
                    data = serialHandle.ReadByte();

                    if (reading)
                    {
                        if (data != 42)
                        {
                            if (data != 33)
                                tempSentence[indexSentence] = data;
                            indexSentence++;
                        }
                        else
                        {
                            imuData = new IMUData().Deserialize(new string(Encoding.UTF8.GetChars(tempSentence))) as IMUData;
                            Debug.Print("Read data from IMU:" + imuData.Serialize());
                            reading = false;
                        }
                    }
                    else
                    {
                        if (data == 33)
                        {
                            indexSentence = 0;
                            reading = true;
                        }
                    }
                }
            }
        }
        #endregion

        #region IDisposable
        public void Dispose()
        {
            serialHandle.Close();
            serialHandle.Dispose();
        } 
        #endregion
    }

    public static class Extensions
    {

        private static byte[] tempBuffer = new byte[1];
        public static byte ReadByte(this SerialPort port)
        {
            port.Read(tempBuffer, 0, 1);
            return tempBuffer[0];
        }
    }
}

namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
    public sealed class ExtensionAttribute : Attribute { }

}
